/* 
 * File:   BGTexture.cpp
 * Author: Davit Vardanyan
 * 
 * Created on December 19, 2012, 10:20 AM
 */

#include <iostream>
#include "BGTexture.h"
#include <stdio.h>
#include <png.h>

bool loadPngImage(char *name, int &outWidth, int &outHeight, bool &outHasAlpha, GLubyte **outData) {
	    png_structp png_ptr;
	    png_infop info_ptr;
	    unsigned int sig_read = 0;
	    int color_type, interlace_type;
	    FILE *fp;
	 
	    if ((fp = fopen(name, "rb")) == NULL)
	        return false;
	 
	    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
	            NULL, NULL, NULL);
	 
	    if (png_ptr == NULL) {
	        fclose(fp);
	        return false;
	    }
	 
	    info_ptr = png_create_info_struct(png_ptr);
	    if (info_ptr == NULL) {
	        fclose(fp);
	        png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
	        return false;
	    }
	 
	    if (setjmp(png_jmpbuf(png_ptr))) {
	        png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
	        fclose(fp);
	        return false;
	    }
	    png_init_io(png_ptr, fp);
	    png_set_sig_bytes(png_ptr, sig_read);
	    png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING | PNG_TRANSFORM_EXPAND, png_voidp_NULL);
	    outWidth = info_ptr->width;
	    outHeight = info_ptr->height;
	    switch (info_ptr->color_type) {
	        case PNG_COLOR_TYPE_RGBA:
	            outHasAlpha = true;
	            break;
	        case PNG_COLOR_TYPE_RGB:
	            outHasAlpha = false;
	            break;
	        default:
	            std::cout << "Color type " << info_ptr->color_type << " not supported" << std::endl;
	            png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
	            fclose(fp);
	            return false;
	    }
	    unsigned int row_bytes = png_get_rowbytes(png_ptr, info_ptr);
	    *outData = (unsigned char*) malloc(row_bytes * outHeight);
	 
	    png_bytepp row_pointers = png_get_rows(png_ptr, info_ptr);
	 
	    for (int i = 0; i < outHeight; i++) {
	        memcpy(*outData+(row_bytes * (outHeight-1-i)), row_pointers[i], row_bytes);
	    }
	 
	    png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
	    fclose(fp);
	    return true;
	}


BGTexture::BGTexture(int count) {
    texCount = count;
    TexId = new GLuint[texCount];
}

BGTexture::BGTexture(const BGTexture& orig) {
    TexId = orig.TexId;
}

BGTexture::~BGTexture() {
    delete TexId;
}

int BGTexture::getTexCount()
{
    return texCount;
}

void BGTexture::initTextures()
{
    	int width;
	int height;
        bool hasAlpha;
        char **name = new char*[texCount];
	GLubyte  *data[texCount];
	glGenTextures(texCount, TexId);
        name[0] = "res/black.png";
        name[1] = "res/white.png";
        name[2] = "res/background.png";
        name[3] = "res/cube1.png";
        name[4] = "res/cube2.png";
        name[5] = "res/cube3.png";
        name[6] = "res/cube4.png";
        name[7] = "res/cube5.png";
        name[8] = "res/cube6.png";
        
        for (int i = 0; i < texCount; ++i) {
            ///////////////////////
            bool success = loadPngImage(name[i], width, height, hasAlpha, &data[i]);
	    if (!success) {
	        std::cout << "Unable to load png file" << std::endl;
	        return;
	    }
	    std::cout << "Image loaded " << width << " " << height << " alpha " << hasAlpha << std::endl;
            /////////////////////
            glBindTexture (GL_TEXTURE_2D,TexId[i]);            
            glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	    glTexImage2D(GL_TEXTURE_2D, 0, hasAlpha ? 4 : 3, width,
	            height, 0, hasAlpha ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE,
	            data[i]);
	    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
	    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
	    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	    glEnable(GL_TEXTURE_2D);
	    glShadeModel(GL_FLAT);        
        }
}

GLuint BGTexture::getTexture(texture name)
{
    return TexId[name];
}

